package com.huilian.iotbox.admin.wap.service.impl;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.iot.model.v20180120.PubResponse;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.huilian.iotbox.admin.wap.dao.DeviceDao;
import com.huilian.iotbox.admin.wap.dao.DisplayRackItemDao;
import com.huilian.iotbox.admin.wap.producer.RabbitProducer;
import com.huilian.iotbox.admin.wap.service.*;
import com.huilian.iotbox.aliyun.openapi.MessageBrokerManager;
import com.huilian.iotbox.aliyun.service.PubService;
import com.huilian.iotbox.data.cmd.*;
import com.huilian.iotbox.data.common.RedisKey;
import com.huilian.iotbox.data.common.ServerResponse;
import com.huilian.iotbox.data.constants.IotConstant;
import com.huilian.iotbox.data.dto.*;
import com.huilian.iotbox.data.enums.*;
import com.huilian.iotbox.data.po.*;
import com.huilian.iotbox.data.properties.ConfigProperties;
import com.huilian.iotbox.data.service.*;
import com.huilian.iotbox.data.utils.DateTimeUtils;
import com.huilian.iotbox.data.utils.IotBoxUtil;
import com.huilian.iotbox.data.utils.SnowflakeIdWorker;
import com.huilian.iotbox.data.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class DeviceServiceImpl implements DeviceService {

    @Value("${huilian.iot.productKey}")
    private String productKey;
    @Autowired
    private DeviceDao deviceDao;
    @Autowired
    private PubService pubService;
    @Autowired
    private AgencyService agencyService;
    @Autowired
    private ProductService productService;
    @Autowired
    private ConfigProperties configProperties;
    @Autowired
    private DisplayRackItemDao displayRackItemDao;
    @Autowired
    private DisplayRackService displayRackService;
    @Autowired
    private BlueToothPubService blueToothPubService;
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private MerchantStoreService merchantStoreService;
    @Autowired
    private PushConfigUserService pushConfigUserService;
    @Autowired
    private MerchantBannerService merchantBannerService;
    @Autowired
    private DisplayRackItemService displayRackItemService;
    @Autowired
    private RedisTemplate<String, Serializable> redisCacheTemplate;
    @Autowired
    private CommodityStoreUpDownService commodityStoreUpDownService;
    @Autowired
    private CommodityStockRecordService commodityStockRecordService;
    @Autowired
    private CommodityStockRecordItemService commodityStockRecordItemService;
    @Autowired
    private AppletOrOfficialAccountCommonService appletOrOfficialAccountCommonService;

    @Override
    public ServerResponse getDeviceByManufacturers(UserInfo userInfo) {
        final PushConfigUser pushConfigUser = pushConfigUserService.findOneByUserId(userInfo);
        if (!StringUtils.isEmpty(pushConfigUser)) {
            return ServerResponse.createBySuccess(pushConfigUser.getAppletOrOfficialAccountId());
        }

        Integer appletOrOfficialAccountId = this.groupAgencyIdReturnOfficialAccount(userInfo);
        if (StringUtils.isEmpty(appletOrOfficialAccountId)) {
            appletOrOfficialAccountId = 3;
        }
        return ServerResponse.createBySuccess(appletOrOfficialAccountId);
    }

    /**
     * 返回专属公众号
     *
     * @param userInfo
     * @return
     */
    @Override
    public Integer groupAgencyIdReturnOfficialAccount(UserInfo userInfo) {
        Integer appletOrOfficialAccountId = null;
        List<Integer> agencyIdList = deviceDao.groupAgencyId(userInfo);
        for (Integer agencyId : agencyIdList) {
            Agency agency = agencyService.findOneAgencyById(agencyId);
            if (!StringUtils.isEmpty(agency) && !StringUtils.isEmpty(agency.getDedicatedOfficialAccount())) {
                appletOrOfficialAccountId = agency.getDedicatedOfficialAccount();
                break;
            }
        }
        return appletOrOfficialAccountId;
    }


    /**
     * 根据条件和分页查集合
     *
     * @param deviceDto
     * @return
     */
    @Override
    public ServerResponse findAllDeviceByConditionAndPage(DeviceDto deviceDto) {
        long startTime = System.currentTimeMillis();

        /**
         * 默认查询当前用户的所有店铺下面的设备
         * 根据店铺id查设备
         */
        PageHelper.startPage(deviceDto.getPageNum(), deviceDto.getPageSize());
        // 获取当前店铺的所有商户id
        List<DeviceVo> deviceVoList = deviceDao.findStoreAndBindingDeviceList(deviceDto);
        PageInfo<DeviceVo> pageInfo = new PageInfo(deviceVoList);
        List<DeviceVo> deviceVos = new ArrayList<>();
        final SystemConfig systemConfig = systemConfigService.findOneSystemConfigById(1);
        for (DeviceVo deviceVo : deviceVoList) {
            List<DeviceVo> deviceList = deviceDao.findAllDeviceByMerchantStoreId(deviceDto, deviceVo.getMerchantStoreId());
            deviceList.forEach(data -> {
                if (StringUtils.isEmpty(data.getMeasuringUnit())) {
                    data.setMeasuringUnit(systemConfig.getDefaultMeasuringUnit());
                }
                if (data.getDeviceTypeId().equals(DeviceTypeEnum.VENDING_MACHINE.getCode()) || data.getDeviceTypeId().equals(DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode())
                        || data.getDeviceTypeId().equals(DeviceTypeEnum.BLEND_VENDING_MACHINE.getCode())) {
                    Integer freightLaneCount = 0;
                    Integer capacityCount = 0;
                    Integer stockCount = 0;
                    List<DisplayRackItemVo> displayRackItemVoList = displayRackItemService.findDisplayRackItemByDisplayRackId(data.getDrId());
                    for (DisplayRackItemVo displayRackItemVo : displayRackItemVoList) {
                        if (!ObjectUtils.isEmpty(displayRackItemVo.getCommodityId())) {
                            freightLaneCount++;
                            capacityCount += displayRackItemVo.getCapacity();
                            stockCount += displayRackItemVo.getStock();
                        }
                    }
                    data.setFreightLaneCount(freightLaneCount);
                    data.setCapacityCount(capacityCount);
                    data.setStockCount(stockCount);
                    data.setScarceStock(capacityCount - stockCount);
                }

                if (!StringUtils.isEmpty(data.getDisplayRackItemVoList())) {
                    data.getDisplayRackItemVoList().sort(Comparator.comparing(DisplayRackItemVo::getHierarchy));
                }

                if (
                        DeviceTypeEnum.ONE_TO_MANY_BOXES.getCode().equals(data.getDeviceTypeId())
                                || DeviceTypeEnum.GASHAPON_MACHINE.getCode().equals(data.getDeviceTypeId())
                ) {
                    for (DisplayRackItemVo displayRackItemVo : data.getDisplayRackItemVoList()) {
                        displayRackItemVo.setRateEach(displayRackItemVo.getDriRateEach());
                    }
                } else {
                    for (DisplayRackItemVo displayRackItemVo : data.getDisplayRackItemVoList()) {
                        displayRackItemVo.setRateEach(data.getRateEach());
                    }
                }
                if (!StringUtils.isEmpty(data.getGiftType()) && data.getGiftType() == 1) {
                    if (StringUtils.isEmpty(data.getDisplayRackItemVoList()) || data.getDisplayRackItemVoList().size() == 0) {
                        // 初始化部分不绑定礼品的设备
                        List<DisplayRackItemVo> displayRackItemVoList = new ArrayList<>();
                        DisplayRackItemVo displayRackItemVo = new DisplayRackItemVo();
                        displayRackItemVo.setRateEach(data.getRateEach());
                        displayRackItemVo.setHierarchy(1);
                        displayRackItemVoList.add(displayRackItemVo);
                        data.setDisplayRackItemVoList(displayRackItemVoList);
                    }
                }

                Map<Integer, DeviceItem> deviceItemMap = new HashMap<>();
                if (!StringUtils.isEmpty(data.getDeviceItemList()) && data.getDeviceItemList().size() > 0) {
                    deviceItemMap = data.getDeviceItemList().stream().collect(Collectors.toMap(DeviceItem::getPositionId, a -> a, (k1, k2) -> k1));
                }
                // 自动生成仓位名称
                for (DisplayRackItemVo displayRackItemVo : data.getDisplayRackItemVoList()) {
                    StringBuilder stringBuilder = new StringBuilder("仓位 ");
                    if (!StringUtils.isEmpty(displayRackItemVo.getHierarchy()) && !StringUtils.isEmpty(displayRackItemVo.getFreightLane())) {
                        stringBuilder.append(displayRackItemVo.getHierarchy());
//                        stringBuilder.append("-");
//                        stringBuilder.append(displayRackItemVo.getFreightLane());
                    } else if (!StringUtils.isEmpty(displayRackItemVo.getHierarchy())) {
                        stringBuilder.append(displayRackItemVo.getHierarchy());
                    } else if (!StringUtils.isEmpty(displayRackItemVo.getFreightLane())) {
                        stringBuilder.append(displayRackItemVo.getFreightLane());
                    }
                    displayRackItemVo.setLocationName(stringBuilder.toString());

                    if (DeviceTypeEnum.ONE_TO_MANY_BOXES.getCode().equals(data.getDeviceTypeId())) {
                        final DeviceItem deviceItem = deviceItemMap.get(DeviceItemPositionEnum.getPositionId(displayRackItemVo.getHierarchy()));
                        if (!StringUtils.isEmpty(deviceItem)) {
                            displayRackItemVo.setProductId(deviceItem.getProductId());
                        }
                    }
                }
            });
            deviceVo.setDeviceList(deviceList);
            deviceVos.add(deviceVo);
        }

        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        System.out.println("方法执行时间（毫秒）：" + duration);
        pageInfo.setList(deviceVos);
        return ServerResponse.createBySuccess(pageInfo);
    }

    @Override
    public PageInfo<DeviceVo> findVendingMachineByConditionAndPage(DeviceDto deviceDto) {
        PageHelper.startPage(deviceDto.getPageNum(), deviceDto.getPageSize());
        //获取售货机的设备信息
        List<Integer> vendingMachine = new ArrayList<>();
        vendingMachine.add(DeviceTypeEnum.VENDING_MACHINE.getCode());
        vendingMachine.add(DeviceTypeEnum.SCREEN_VENDING_MACHINE.getCode());
        vendingMachine.add(DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode());
        vendingMachine.add(DeviceTypeEnum.BLEND_VENDING_MACHINE.getCode());
        deviceDto.setVendingMachine(vendingMachine);
        deviceDto.setEnabled(true);
        DisplayRackItemDto displayRackItemDto1 = new DisplayRackItemDto();
        displayRackItemDto1.setIsDelete(false);
        displayRackItemDto1.setNotBound(true);
        displayRackItemDto1.setIsOutOfStock(true);
        List<DeviceVo> deviceVoList = deviceDao.findStoreAndBindingDeviceList(deviceDto);
        for (DeviceVo d : deviceVoList) {

            List<DeviceVo> deviceList = deviceDao.findAllVendingMachineByMerchantStoreId(deviceDto, d.getMerchantStoreId());
            for (DeviceVo vending : deviceList) {
                DisplayRackItemDto displayRackItemDto = new DisplayRackItemDto();
                displayRackItemDto.setDeviceId(vending.getId());
                //缺货数
                DisplayRackItemVo displayRackItemVo = displayRackItemService.findOutOfStockByDeviceId(displayRackItemDto);
                vending.setOutOfStock(displayRackItemVo.getOutOfStock());

                displayRackItemDto1.setDeviceId(vending.getId());
                List<DisplayRackItemVo> displayRackItemVoList = displayRackItemDao.findCommodityLackStockByDeviceId(displayRackItemDto1);
                vending.setArrowDoubleShow(false);
                vending.setDisplayRackItemVoList(displayRackItemVoList);
            }
            d.setDeviceList(deviceList);
        }

        return new PageInfo(deviceVoList);
    }


    @Override
    public ServerResponse findIsBinding(DeviceDto deviceDto) {
        DeviceVo isBindingDeviceVo = deviceDao.findOneDeviceByDeviceNo(deviceDto.getDeviceNo());
        if (ObjectUtils.isEmpty(isBindingDeviceVo)) {
            return ServerResponse.createByError("设备号有误,请联系平台");
        }

        if (StringUtils.isEmpty(isBindingDeviceVo.getMerchantStoreId())) {
            return ServerResponse.createBySuccess();
        }

        // 检查是否已绑定在当前运营下
        Integer[] merchantStoreId = merchantStoreService.findAllMerchantStoreIdByUserId(deviceDto.getUserInfo());
        Map<String, String> map = new HashMap<>();
        for (int i = 0; i < merchantStoreId.length; i++) {
            if (isBindingDeviceVo.getMerchantStoreId().equals(merchantStoreId[i])) {
                map.put("code", "my");
                map.put("msg", "设备已绑定，请勿重复操作");
                return ServerResponse.createBySuccess(map);
            }
        }
        if (!isBindingDeviceVo.getMerchantStoreId().equals(-1)) {
            map.put("code", "other");
            map.put("msg", "设备已绑定在其他运营商名下");
            return ServerResponse.createBySuccess(map);
        }
        return ServerResponse.createBySuccess();
    }

    @Override
    public List<DeviceVo> findBindingDevice(DeviceDto deviceDto) {
        return deviceDao.findBindingDevice(deviceDto);
    }


    @Override
    public PageInfo<DeviceVo> deviceList(DeviceDto deviceDto) {
        PageHelper.startPage(deviceDto.getPageNum(), deviceDto.getPageSize());
        final List<DeviceVo> device = deviceDao.findDevice(deviceDto);
        return new PageInfo<>(device);
    }


    @Override
    public DeviceVo findOneDeviceByDeviceNo(String deviceNo) {

        return deviceDao.findOneDeviceByDeviceNo(deviceNo);
    }

    @Override
    public DeviceVo findOneDeviceByDeviceNoJoinProduct(String deviceNo) {
        DeviceDto deviceDto = new DeviceDto();
        deviceDto.setDeviceNo(deviceNo);
        deviceDto.setDeviceTypeId(DeviceTypeEnum.VENDING_MACHINE.getCode());
        return deviceDao.findOneDeviceByDeviceNoJoinProduct(deviceDto);
    }


    @Override
    public ServerResponse updateDeviceRemarkNameById(DeviceDto deviceDto) {
        if (StringUtils.isEmpty(deviceDto.getId())) {
            return ServerResponse.createByErrorMessage("缺少参数");
        }

        DeviceVo deviceVo = deviceDao.findOneDeviceByDeviceNoAndPermission(deviceDto);
        if (StringUtils.isEmpty(deviceVo)) {
            return ServerResponse.createByErrorMessage("设备不存在");
        }

        deviceDao.updateDeviceRemarkNameById(deviceDto);
        return ServerResponse.createBySuccess();
    }


    @Override
    public List<DeviceVo> findAllDeviceByMerchantStoreIdArray(DeviceDto deviceDto) {

        if (StringUtils.isEmpty(deviceDto)) {
            return new ArrayList<>();
        }

        return deviceDao.findAllDeviceByMerchantStoreIdArray(deviceDto);
    }

    /**
     * 根据场地数组查出对应的设备
     *
     * @param deviceDto
     * @return
     */
    @Override
    public ServerResponse findAllDeviceByMerchantStoreId(DeviceDto deviceDto) {

        if (deviceDto.getMerchantStoreIdList().length == 0) {
            return ServerResponse.createByErrorMessage("场地ID不能为空");
        }
        //获取是否展示售货机上传广告
        DeviceVo deviceVo = new DeviceVo();
        List<Integer> deviceTypeIdListExist = new ArrayList<>();
        deviceTypeIdListExist.add(DeviceTypeEnum.VENDING_MACHINE.getCode());
        deviceTypeIdListExist.add(DeviceTypeEnum.SCREEN_VENDING_MACHINE.getCode());
        deviceTypeIdListExist.add(DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode());
        deviceTypeIdListExist.add(DeviceTypeEnum.ONE_TO_MANY_BOXES.getCode());
        deviceDto.setDeviceTypeIdList(deviceTypeIdListExist);
        deviceVo.setWhetherToDisplayVendingMachine(deviceDao.doYouHaveACertainDevice(deviceDto));

        List<Integer> deviceTypeIdList = new ArrayList<>();
        deviceTypeIdList.add(DeviceTypeEnum.SUPER_MONEY_CHANGER.getCode());
        deviceDto.setDeviceTypeIdList(deviceTypeIdList);
        deviceVo.setExhibitCurrencyExchangeMachine(deviceDao.doYouHaveACertainDevice(deviceDto));
        List<DeviceVo> deviceVoList = deviceDao.findAllDeviceByMerchantStoreIdArray(deviceDto);

        if (deviceVoList.size() == 0) {
            deviceVo.setDeviceVo(new ArrayList<>());
            return ServerResponse.createBySuccess(deviceVo);
        }

        Integer[] deviceIdArray = new Integer[deviceVoList.size()];
        for (int i1 = 0; i1 < deviceVoList.size(); i1++) {
            deviceIdArray[i1] = deviceVoList.get(i1).getId();
        }

//        Integer[] merchantBannerTypeArray = new Integer[]{
//                MerchantBannerTypeEnum.TOP_EXCLUSIVE.getCode(),
//                MerchantBannerTypeEnum.FULL_EXCLUSIVE.getCode()
//        };
        List<DeviceVo> deviceVoList1 = merchantBannerService.findMerchantBannerByDeviceId(deviceDto, deviceIdArray);
        deviceVo.setDeviceVo(deviceVoList1);
        return ServerResponse.createBySuccess(deviceVo);
    }

    /**
     * @param merchantStoreId
     * @param automaticCoin
     */
    @Override
    public void updateDeviceAutomaticCoin(Integer merchantStoreId, boolean automaticCoin) {
        DeviceDto deviceDto = new DeviceDto();
        deviceDto.setMerchantStoreId(merchantStoreId);
        List<Device> deviceList = deviceDao.findAllDeviceByCondition(deviceDto);

        if (deviceList.size() == 0) {
            return;
        }

        List<Device> updateDeviceList = new ArrayList<>();
        for (Device device : deviceList) {
            Device d = new Device();
            d.setId(device.getId());
            d.setAutomaticCoin(automaticCoin);
            updateDeviceList.add(d);
        }

        deviceDao.updateBatchDeviceById(updateDeviceList);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServerResponse shiftDevice(DeviceDto deviceDto) {
        if (StringUtils.isEmpty(deviceDto.getId())) {
            return ServerResponse.createByErrorMessage("设备ID不能为空");
        }
        //查询新设备号
        DeviceVo newDvice = this.findOneDeviceByDeviceNo(deviceDto.getNewDeviceNo());
        if (ObjectUtils.isEmpty(newDvice)) {
            return ServerResponse.createByErrorMessage("新设备不存在");
        }
        //旧设备号
        Device oneDeviceByCondition = this.findOneDeviceByCondition(deviceDto);
        if (ObjectUtils.isEmpty(oneDeviceByCondition)) {
            return ServerResponse.createByErrorMessage("旧设备不存在");
        }
        if (oneDeviceByCondition.getDeviceNo().equals(deviceDto.getDeviceNo())) {
            Device device = new Device();
            device.setId(newDvice.getId());
            device.setDeviceNo(deviceDto.getNewDeviceNo());
            device.setAlias(oneDeviceByCondition.getAlias());
            device.setDeviceTypeId(oneDeviceByCondition.getDeviceTypeId());
            device.setMerchantStoreId(oneDeviceByCondition.getMerchantStoreId());
            device.setStatus(oneDeviceByCondition.getStatus());
            device.setRateEach(oneDeviceByCondition.getRateEach());
            device.setRemarkName(oneDeviceByCondition.getRemarkName());
            device.setChargingPileRateId(oneDeviceByCondition.getChargingPileRateId());
            device.setGameTime(oneDeviceByCondition.getGameTime());
            device.setAutomaticCoin(oneDeviceByCondition.getAutomaticCoin());
            device.setNetworkIntensity(oneDeviceByCondition.getNetworkIntensity());
            //修改新设备号
            Integer result = deviceDao.update(device);
            if (result == 0) {
                throw new RuntimeException("修改失败");
            }
            //修改旧设备号
            oneDeviceByCondition.setMerchantStoreId(-1);
            oneDeviceByCondition.setStatus(4);
            Integer pastResult = deviceDao.update(oneDeviceByCondition);
            if (pastResult == 0) {
                throw new RuntimeException("修改旧设备出错");
            }
            //display_rack_item表的：把deviceId改成新的设备ID
            DisplayRackItemDto displayRackItemDto = new DisplayRackItemDto();
            displayRackItemDto.setDeviceId(deviceDto.getId());
            displayRackItemDto.setIsDelete(false);
            List<DisplayRackItemVo> displayRackItemVoList = displayRackItemService.findDisplayRackItemByDeviceId(displayRackItemDto);
            //循环修改
            for (DisplayRackItemVo displayRackItemVo : displayRackItemVoList) {
                DisplayRack updateDisplayRack = new DisplayRack();
                updateDisplayRack.setId(displayRackItemVo.getDisplayRackId());
                updateDisplayRack.setDeviceId(newDvice.getId());
                Integer resultGoodsStock = displayRackService.updateById(updateDisplayRack);
                if (resultGoodsStock == 0) {
                    throw new RuntimeException("修改失败");
                }
            }
        }
        return ServerResponse.createBySuccess();
    }

    /**
     * 根据条件查集合
     *
     * @param deviceDto
     * @return
     */
    @Override
    public List<Device> findAllDeviceByCondition(DeviceDto deviceDto) {
        return deviceDao.findAllDeviceByCondition(deviceDto);
    }

    /**
     * 根据条件查单个
     *
     * @param deviceDto
     * @return
     */
    @Override
    public Device findOneDeviceByCondition(DeviceDto deviceDto) {
        return deviceDao.findOneDeviceByCondition(deviceDto);
    }


    @Override
    public ServerResponse updateDeviceParamsById(DeviceDto deviceDto) {
        DeviceVo deviceVo = deviceDao.findOneDeviceByDeviceNo(deviceDto.getDeviceNo());

        return ServerResponse.createBySuccess();
    }

    @Override
    public ServerResponse statisticsOnlineDevice(UserInfo userInfo) {
        int onLine = 0;
        List<DeviceVo> deviceList = deviceDao.statisticsOnlineDevice(userInfo);
        for (DeviceVo device : deviceList) {
            if (device.getNetworkIntensity() > 5) {
                onLine++;
            }
        }
        DeviceVo deviceVo = new DeviceVo();
        deviceVo.setOnlineCount(onLine);

        if (deviceList.size() > 0) {
            deviceVo.setTotalLineCount(deviceList.size());
        }
        return ServerResponse.createBySuccess(deviceVo);
    }

    @Override
    public ServerResponse findDevice(DeviceDto deviceDto) {
        return ServerResponse.createBySuccess(deviceDao.findDevice(deviceDto));
    }

    @Override
    public ServerResponse findDevice_v2(DeviceDto deviceDto) {
        return ServerResponse.createBySuccess(deviceDao.findDevice_v2(deviceDto));
    }

    @Override
    public ServerResponse findDevice_v3(DeviceDto deviceDto) {
        return ServerResponse.createBySuccess(deviceDao.findDevice_v3(deviceDto));
    }


    @Override
    public Integer findCountDeviceByMerchantStoreId(DeviceDto deviceDto) {
        return deviceDao.findCountDeviceByMerchantStoreId(deviceDto);
    }


    @Override
    public DeviceVo findStatisticsDevice(DeviceDto deviceDto) {
        DeviceVo deviceVo = deviceDao.findStoreStats(deviceDto);

        return deviceVo;
    }

    /**
     * 查询售货机全部 在线 离线
     */
    @Override
    public DeviceVo findVendingMachineDevice(DeviceDto deviceDto) {
        List<Integer> vendingMachine = new ArrayList<>();
        vendingMachine.add(DeviceTypeEnum.VENDING_MACHINE.getCode());
        vendingMachine.add(DeviceTypeEnum.SCREEN_VENDING_MACHINE.getCode());
        vendingMachine.add(DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode());
        vendingMachine.add(DeviceTypeEnum.BLEND_VENDING_MACHINE.getCode());
        deviceDto.setVendingMachine(vendingMachine);
        deviceDto.setEnabled(true);
        DeviceVo deviceVo = deviceDao.findStoreStats(deviceDto);
        return deviceVo;
    }

    @Override
    public DeviceVo getDeviceById(Integer deviceId) {
        return deviceDao.getDeviceById(deviceId);
    }

    @Override
    public List<DeviceVo> findAllDeviceByIdAndPermission(DeviceDto deviceDto) {
        return deviceDao.findAllDeviceByIdAndPermission(deviceDto);
    }


    @Override
    public Integer findDeviceCountByMerchantStoreId(DeviceDto deviceDto) {
        return deviceDao.findDeviceCountByMerchantStoreId(deviceDto);
    }


    /**
     * 禁用/解除禁用 单个设备
     */
    @Override
    public ServerResponse upDisableDevice(DeviceDto deviceDto) {
        Integer result = deviceDao.updateDeviceById(deviceDto);
        if (result == 0) {
            throw new RuntimeException("修改禁用状态失败");
        }
        return ServerResponse.createBySuccess();
    }

    /**
     * 单设备转场
     */
    @Override
    public ServerResponse deviceTransition(DeviceDto deviceDto) {
        //不包含1，2，3，无权限操作
        Integer[] roleIdArray = {
                RoleEnum.AGENT.getRoleId(),
                RoleEnum.SUPER_ADMINISTRATOR.getRoleId(),
                RoleEnum.MERCHANT.getRoleId()
        };
        boolean contains = Arrays.asList(roleIdArray).contains(deviceDto.getUserInfo().getRoleId());
        if (!contains) {
            return ServerResponse.createByErrorMessage("暂无操作权限");
        }
        if (StringUtils.isEmpty(deviceDto.getDeviceNo())) {
            return ServerResponse.createByErrorMessage("该设备不存在");
        }
        if (StringUtils.isEmpty(deviceDto.getNewMerchantStore())) {
            return ServerResponse.createByErrorMessage("要转场的场地不存在！");
        }
        try {
            DeviceDto me = new DeviceDto();
            me.setMerchantStoreId(deviceDto.getNewMerchantStore());
            List<DeviceVo> deviceVoList = deviceDao.findDeviceBydeviceIdGrouping(me);
            DeviceVo deviceVo = deviceDao.findOneDeviceByDeviceNo(deviceDto.getDeviceNo());
            if (StringUtils.isEmpty(deviceVo)) {
                return ServerResponse.createByErrorMessage("找不到设备");
            }
            DeviceDto dd = new DeviceDto();
            dd.setId(deviceVo.getId());
            dd.setAlias(deviceVo.getAlias());
            dd.setMerchantStoreId(deviceDto.getNewMerchantStore());
            for (DeviceVo dv : deviceVoList) {
                //转移的设备号码和新的场地的设备号码出现一致
                if (!StringUtils.isEmpty(dv.getAlias()) &&
                        !StringUtils.isEmpty(deviceVo.getAlias()) &&
                        deviceVo.getAlias().equals(dv.getAlias())) {
                    dd.setAlias(deviceVoList.get(0).getAlias() + 1);
                    break;
                }
            }
            deviceDao.updateDeviceById(dd);
            //售货机需要更改货道场地
            if (DeviceTypeEnum.VENDING_MACHINE.getCode().equals(deviceVo.getDeviceTypeId()) || DeviceTypeEnum.SCREEN_VENDING_MACHINE.getCode().equals(deviceVo.getDeviceTypeId())
                    || DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode().equals(deviceVo.getDeviceTypeId())) {
                DisplayRack updateDisplayRack = new DisplayRack();
                updateDisplayRack.setDeviceId(deviceVo.getId());
                updateDisplayRack.setMerchantStoreId(deviceDto.getNewMerchantStore());
                displayRackService.updateById(updateDisplayRack);
            } else {
                //其他的类型修改删除状态
                DisplayRack updateDisplayRack = new DisplayRack();
                updateDisplayRack.setDeviceId(deviceVo.getId());
                updateDisplayRack.setIsDelete(true);
                displayRackService.updateById(updateDisplayRack);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ServerResponse.createBySuccess("转场成功！");
    }


    @Override
    public Integer updateCommodityGroupSwitch(DeviceDto deviceDto) {
        if (ObjectUtils.isEmpty(deviceDto.getId())) {
            throw new RuntimeException("缺少参数:设备ID");
        }
        int count = deviceDao.findDeviceCountByMerchantStoreId(deviceDto);
        if (count < 0) {
            throw new RuntimeException("设备不存在或账号无权限");
        }
        return deviceDao.updateCommodityGroupSwitch(deviceDto);
    }

    @Override
    public DeviceVo findDeviceVoById(DeviceDto deviceDto) {
        return deviceDao.findOneDeviceByIdAndPermission(deviceDto);
    }

    @Override
    public Integer updateCustomerBuySet(DeviceDto deviceDto) {
        if (ObjectUtils.isEmpty(deviceDto.getId())) {
            throw new RuntimeException("缺少参数:设备ID");
        }
        int count = deviceDao.findDeviceCountByMerchantStoreId(deviceDto);
        if (count < 0) {
            throw new RuntimeException("设备不存在或账号无权限");
        }
        DeviceVo deviceVo = getDeviceById(deviceDto.getId());
        if (!ObjectUtils.isEmpty(deviceVo.getIsVendmach())
                && deviceVo.getIsVendmach()) {
            String command = PositiveDataFrameCMD.penetrate(HuiLianDuiBiJiPositiveDataFrameCMD.boundDeviceOrUnBindOrEditDiscountPackage());
            log.info("安卓设备需要发 信息变动 信号command:" + command);
            boolean pub = pubService.pub(command, deviceVo.getDeviceNo(), productKey);
        }
        if (!StringUtils.isEmpty(deviceDto.getLightControl()) || !StringUtils.isEmpty(deviceDto.getTemperatureControl())) {
            String command = PositiveDataFrameCMD.penetrate(VendmachPositiveDataFrameCMD.switchConfiguration(deviceVo.getDeviceNo(), deviceDto));
            log.info("协议{}", command);
            pubService.pub(command, deviceVo.getDeviceNo(), productKey);
        }
        return deviceDao.updateCustomerBuySet(deviceDto);
    }

    /**
     * 查询售货机设备
     */
    @Override
    public ServerResponse findSalesDevice(DeviceDto deviceDto) {
        return ServerResponse.createBySuccess(deviceDao.findSalesDevice(deviceDto));
    }

    @Override
    public List<DeviceVo> findGateGateDevice(MerchantStoreVo merchantStoreVo) {
        return deviceDao.findGateGateDevice(merchantStoreVo);
    }

    @Override
    public ServerResponse findClientUrl(DeviceDto deviceDto) {

        if (StringUtils.isEmpty(deviceDto.getDeviceNo())) {
            return ServerResponse.createByErrorMessage("设备号不能为空");
        }
        DeviceVo deviceVo = deviceDao.findOneDeviceByDeviceNoAndPermission(deviceDto);
        if (StringUtils.isEmpty(deviceVo)) {
            return ServerResponse.createByErrorMessage("设备不存在或无权限");
        }

        final Agency agency = agencyService.findOneAgencyById(deviceVo.getAgencyId());

        MerchantStoreDto merchantStoreDto = new MerchantStoreDto();
        merchantStoreDto.setUserInfo(deviceDto.getUserInfo());
        merchantStoreDto.setId(deviceVo.getMerchantStoreId());
        final MerchantStore merchantStore = merchantStoreService.findOneMerchantStoreByIdAndPermission(merchantStoreDto);

        /**
         * 专属规则优先级：商家-场地 > 合作伙伴 > 平台
         * 商家：-
         * 合作伙伴：蓝牙 > 专属微信公众号 > 专属微信小程序 = 专属支付宝小程序
         * 平台
         */
        StringBuffer qrLink = new StringBuffer();
        if (!StringUtils.isEmpty(merchantStore.getDedicatedWeChatApplet()) || !StringUtils.isEmpty(merchantStore.getDedicatedALiApplet()) || !StringUtils.isEmpty(merchantStore.getDedicatedOfficialAccount())) {
            // 商家-场地专属规则
            qrLink.append(configProperties.getClientBackEndUrl());
            if (deviceVo.getIsBluetooth()) {
                // 蓝牙，专属微信小程序
                log.info("蓝牙，商家专属微信小程序-处理");
                qrLink.append("/client/applet/");
                qrLink.append(merchantStore.getId());
                qrLink.append("/deviceNo/");
            } else if (!StringUtils.isEmpty(merchantStore.getDedicatedWeChatApplet())) {
                // 专属微信小程序
                log.info("商家专属微信小程序-处理");
                qrLink.append("/client/applet/");
                qrLink.append(merchantStore.getId());
                qrLink.append("/deviceNo/");
            } else if (!StringUtils.isEmpty(merchantStore.getDedicatedALiApplet())) {
                // 专属支付宝小程序
                log.info("商家专属支付宝小程序-处理");
                qrLink.append("/client/applet/");
                qrLink.append(merchantStore.getId());
                qrLink.append("/deviceNo/");
            } else if (!StringUtils.isEmpty(merchantStore.getDedicatedOfficialAccount())) {
                // 专属微信公众号
                log.info("商家专属微信公众号-处理");
                qrLink.append("/client/applet/");
                qrLink.append(merchantStore.getId());
                qrLink.append("/deviceNo/");
            } else {
                throw new RuntimeException("商家专属规则配置异常");
            }
        } else if (!StringUtils.isEmpty(agency.getDedicatedWeChatApplet()) || !StringUtils.isEmpty(agency.getDedicatedALiApplet()) || !StringUtils.isEmpty(agency.getDedicatedOfficialAccount())) {
            // 合作伙伴专属规则
            AppletOrOfficialAccount appletOrOfficialAccount = null;
            // 蓝牙 > 专属微信公众号 > 专属微信小程序 = 专属支付宝小程序
            if (deviceVo.getIsBluetooth()) {
                // 蓝牙
                log.info("合作伙伴专属微信小程序-处理");
                appletOrOfficialAccount = appletOrOfficialAccountCommonService.findOneById(agency.getDedicatedWeChatApplet());
                if (StringUtils.isEmpty(appletOrOfficialAccount)) {
                    throw new RuntimeException("合作伙伴专属规则配置异常_4");
                }
                if (StringUtils.isEmpty(appletOrOfficialAccount.getDeviceQrCode())) {
                    throw new RuntimeException("合作伙伴专属规则配置异常_5");
                }

                qrLink = new StringBuffer(appletOrOfficialAccount.getUrl());
                qrLink.append("/client/applet/device?d=");
            } else {
                if (!StringUtils.isEmpty(agency.getDedicatedOfficialAccount())) {
                    // 专属微信公众号
                    log.info("合作伙伴专属微信公众号-处理");
                    appletOrOfficialAccount = appletOrOfficialAccountCommonService.findOneById(agency.getDedicatedOfficialAccount());
                } else if (!StringUtils.isEmpty(agency.getDedicatedWeChatApplet())) {
                    // 专属微信小程序
                    log.info("合作伙伴专属微信小程序-处理");
                    appletOrOfficialAccount = appletOrOfficialAccountCommonService.findOneById(agency.getDedicatedWeChatApplet());
                } else if (!StringUtils.isEmpty(agency.getDedicatedALiApplet())) {
                    // 专属支付宝小程序
                    log.info("合作伙伴专属支付宝小程序-处理");
                    appletOrOfficialAccount = appletOrOfficialAccountCommonService.findOneById(agency.getDedicatedALiApplet());
                } else {
                    throw new RuntimeException("合作伙伴专属规则配置异常");
                }

                if (StringUtils.isEmpty(appletOrOfficialAccount)) {
                    throw new RuntimeException("合作伙伴专属规则配置异常_2");
                }

                if (StringUtils.isEmpty(appletOrOfficialAccount.getDeviceQrCode())) {
                    throw new RuntimeException("合作伙伴专属规则配置异常_3");
                }

                qrLink = new StringBuffer(appletOrOfficialAccount.getDeviceQrCode());
            }
        } else {
            // 没有专属，默认平台规则
            if (deviceVo.getIsBluetooth()) {
                // 蓝牙
                qrLink.append(configProperties.getClientBackEndUrl());
                qrLink.append("/client/applet/device?d=");
            } else {
                qrLink = new StringBuffer(configProperties.getDevicePayQrUrl());
            }
        }

        qrLink.append(deviceVo.getDeviceNo());
        if (
                DeviceTypeEnum.GASHAPON_MACHINE.getCode().equals(deviceVo.getDeviceTypeId())
                        || DeviceTypeEnum.ONE_TO_MANY_BOXES.getCode().equals(deviceVo.getDeviceTypeId())
        ) {
            boolean contains = qrLink.toString().contains("?");
            if (!contains) {
                qrLink.append("?");
            }

            if (!StringUtils.isEmpty(deviceDto.getHierarchy())) {
                if (!qrLink.toString().endsWith("&")) {
                    qrLink.append("&");
                }
                qrLink.append("h=");
                qrLink.append(deviceDto.getHierarchy());
            }

            if (!StringUtils.isEmpty(deviceDto.getFreightLane())) {
                if (!qrLink.toString().endsWith("&")) {
                    qrLink.append("&");
                }
                qrLink.append("f=");
                qrLink.append(deviceDto.getFreightLane());
            }
        }

        log.info("qrLink:{}", qrLink);
        return ServerResponse.createBySuccess(qrLink);
    }

    @Override
    public void bluetoothTestResults(String protocol) {
        int deviceNo = IotBoxUtil.singleHex2Int(protocol.substring(10, 26));
        log.info("接收到{}设备蓝牙版回复协议", deviceNo);
        StringBuilder stringBuilder = new StringBuilder(IotConstant.CONTENT_PREFIX);
        stringBuilder.append("1C0126");
        stringBuilder.append(protocol);
        stringBuilder.append("4C");
        stringBuilder.append(IotConstant.CONTENT_SUFFIX);
        log.info("协议:{}", stringBuilder);
        pubService.pub(String.valueOf(stringBuilder), Integer.toString(deviceNo), productKey, true);
    }

    @Override
    public ServerResponse bluetoothOneClickReplenishment(DeviceDto deviceDto) {
        DeviceDto device = deviceDao.findByDevice(deviceDto);
        if (StringUtils.isEmpty(device)) {
            return ServerResponse.createByErrorMessage("设备不存在或暂无该设备权限");
        }
        if (!device.getIsBluetooth()) {
            return ServerResponse.createByErrorMessage("一键补货功能及支持蓝牙开门式售货机");
        }
        DisplayRackItemDto displayRackItemDto = new DisplayRackItemDto();
        displayRackItemDto.setDeviceId(device.getId());
        displayRackItemDto.setIsDelete(false);
        List<OrderItem> orderItemList = new ArrayList<>();
        //库存记录主表
        CommodityStockRecord commodityStockRecord = new CommodityStockRecord();
        //库存记录子表
        List<CommodityStockRecordItem> commodityStockRecordItemList = new ArrayList<>();
        List<DisplayRackItemVo> displayRackVoList = displayRackItemService.findAllChannelInformationByDeviceId(displayRackItemDto);
        List<DisplayRackItemVo> restockingResults = new ArrayList<>();
        for (DisplayRackItemVo displayRackItemVo : displayRackVoList) {
            //库存0 才补货开门并且有绑定商品
            if (displayRackItemVo.getStock() == 0 && !StringUtils.isEmpty(displayRackItemVo.getCommodityId())) {
                OrderItem orderItem = new OrderItem();
                orderItem.setHierarchy(displayRackItemVo.getHierarchy());
                orderItem.setFreightLane(displayRackItemVo.getFreightLane());
                orderItem.setNum(1);
                orderItemList.add(orderItem);

                commodityStockRecord = CommodityStockRecord.builder()
                        .userId(deviceDto.getUserId())
                        .merchantStoreId(device.getMerchantStoreId())
                        .deviceId(device.getId())
                        .description("蓝牙格子机一键补货")
                        .inDisplayRackId(displayRackItemVo.getDisplayRackId())
                        .status(CommodityStockRecordStatusEnum.COMPLETED.getCode())
                        .firstType(CommodityStockRecordFirstTypeEnum.INTO_STOCK_ORDER.getCode())
                        .secondaryType(CommodityStockRecordSecondTypeEnum.VENDING_MACHINE_STORE_RECEIPT.getCode())
                        .operationUserId(deviceDto.getUserId())
                        .createTime(new Date())
                        .build();

                CommodityStockRecordItem commodityStockRecordItem = CommodityStockRecordItem.builder()
                        .commodityId(displayRackItemVo.getCommodityId())
                        .quantity(1)
                        .hierarchy(displayRackItemVo.getHierarchy())
                        .freightLane(displayRackItemVo.getFreightLane())
                        .costPrice(displayRackItemVo.getCostPrice())
                        .retailPrice(displayRackItemVo.getRetailPrice())
                        .stockBefore(0)
                        .stockAfter(1)
                        .costPriceBefore(displayRackItemVo.getCostPrice())
                        .costPriceAfter(displayRackItemVo.getCostPrice())
                        .retailPriceBefore(displayRackItemVo.getRetailPrice())
                        .retailPriceAfter(displayRackItemVo.getRetailPrice())
                        .status(CommodityStockRecordStatusEnum.COMPLETED.getCode())
                        .remark("蓝牙格子机一键补货")
                        .createTime(new Date())
                        .build();
                commodityStockRecordItemList.add(commodityStockRecordItem);

                //修改库存
                DisplayRackItem displayRackItem = new DisplayRackItem();
                displayRackItem.setId(displayRackItemVo.getId());
                displayRackItem.setVersion(displayRackItemVo.getVersion());
                displayRackItem.setStock(1);
                displayRackItemService.update(displayRackItem);

                //补货的货道，返回前端
                DisplayRackItemVo restockingResult = new DisplayRackItemVo();
                restockingResult.setDeviceId(displayRackItemVo.getDeviceId());
                restockingResult.setStock(1);
                restockingResult.setHierarchy(displayRackItemVo.getHierarchy());
                restockingResult.setFreightLane(displayRackItemVo.getFreightLane());
                restockingResult.setCommodityName(displayRackItemVo.getCommodityName());
                restockingResults.add(restockingResult);
            }
        }
        if (!ObjectUtils.isEmpty(orderItemList)) {
            String random = org.apache.commons.lang3.RandomStringUtils.random(6, true, true);
            String command = VendmachPositiveDataFrameCMD.LatticeShipmentTestNew(deviceDto.getDeviceNo(), random, orderItemList, LatticeShipmentTestNewCmdEnum.RESTOCKING.getCode());
            blueToothPubService.pub(command, deviceDto.getDeviceNo(), "merchant_" + deviceDto.getUserId());

            commodityStockRecordService.insert(commodityStockRecord);
            for (CommodityStockRecordItem commodityStockRecordItem : commodityStockRecordItemList) {
                commodityStockRecordItem.setCommodityStockRecordId(commodityStockRecord.getId());
                commodityStockRecordItemService.insert(commodityStockRecordItem);
            }
            return ServerResponse.createBySuccess(restockingResults);
        } else {
            return ServerResponse.createByErrorMessage("所有商品都是满库存,不需要补货啦");
        }

    }

    @Override
    public ServerResponse findOutOfStockItems(DeviceDto deviceDto) {
        DeviceDto device = deviceDao.findByDevice(deviceDto);
        if (StringUtils.isEmpty(device)) {
            return ServerResponse.createByErrorMessage("设备不存在或暂无该设备权限");
        }
        if (!device.getIsBluetooth()) {
            return ServerResponse.createByErrorMessage("一键补货功能及支持蓝牙开门式售货机");
        }
        DisplayRackItemDto displayRackItemDto = new DisplayRackItemDto();
        displayRackItemDto.setDeviceId(device.getId());
        displayRackItemDto.setIsDelete(false);
        List<DisplayRackItemVo> displayRackVoList = displayRackItemService.findAllChannelInformationByDeviceId(displayRackItemDto);
        List<DisplayRackItemVo> restockingResults = new ArrayList<>();
        for (DisplayRackItemVo displayRackItemVo : displayRackVoList) {
            if (displayRackItemVo.getStock() == 0 && !StringUtils.isEmpty(displayRackItemVo.getCommodityId())) {
                //缺货的货道，返回前端
                DisplayRackItemVo restockingResult = new DisplayRackItemVo();
                restockingResult.setDeviceId(displayRackItemVo.getDeviceId());
                restockingResult.setStock(displayRackItemVo.getStock());
                restockingResult.setHierarchy(displayRackItemVo.getHierarchy());
                restockingResult.setFreightLane(displayRackItemVo.getFreightLane());
                restockingResult.setCommodityName(displayRackItemVo.getCommodityName());
                restockingResult.setFileName(displayRackItemVo.getFileName());
                restockingResults.add(restockingResult);
            }
        }
        if (!ObjectUtils.isEmpty(restockingResults)) {
            return ServerResponse.createBySuccess(restockingResults);
        } else {
            return ServerResponse.createByErrorMessage("所有商品都是满库存,不需要补货啦");
        }
    }

    @Override
    public Integer findDeviceCountByUserId(DeviceDto deviceDto) {
        return deviceDao.findDeviceCountByUserId(deviceDto);
    }

    @Override
    public DeviceVo findOneDeviceByIdAndPermission(DeviceDto deviceDto) {
        DeviceVo deviceVo = deviceDao.findOneDeviceByIdAndPermission(deviceDto);

        if (StringUtils.isEmpty(deviceVo)) {
            return null;
        }

        DisplayRackItemDto displayRackItemDto = new DisplayRackItemDto();
        displayRackItemDto.setDeviceId(deviceVo.getId());
        displayRackItemDto.setIsDelete(false);
        DisplayRackVo displayRackVo = displayRackItemService.findDisplayRackAndItemList(displayRackItemDto);
        if (StringUtils.isEmpty(displayRackVo)) {
            deviceVo.setDisplayRackItemVoList(new ArrayList<>());
        } else {
            // 自动生成仓位名称
            for (DisplayRackItemVo displayRackItemVo : displayRackVo.getDisplayRackItemVoList()) {
                StringBuilder stringBuilder = new StringBuilder("仓位 ");
                if (!StringUtils.isEmpty(displayRackItemVo.getHierarchy()) && !StringUtils.isEmpty(displayRackItemVo.getFreightLane())) {
                    stringBuilder.append(displayRackItemVo.getHierarchy());
//                    stringBuilder.append("-");
//                    stringBuilder.append(displayRackItemVo.getFreightLane());
                } else if (!StringUtils.isEmpty(displayRackItemVo.getHierarchy())) {
                    stringBuilder.append(displayRackItemVo.getHierarchy());
                } else if (!StringUtils.isEmpty(displayRackItemVo.getFreightLane())) {
                    stringBuilder.append(displayRackItemVo.getFreightLane());
                }
                displayRackItemVo.setLocationName(stringBuilder.toString());
            }

            deviceVo.setDisplayRackItemVoList(displayRackVo.getDisplayRackItemVoList());
        }

        if (StringUtils.isEmpty(deviceVo.getMeasuringUnit())) {
            SystemConfig systemConfig = systemConfigService.findOneSystemConfigById(1);
            deviceVo.setMeasuringUnit(systemConfig.getDefaultMeasuringUnit());
        }


        return deviceVo;
    }

    @Override
    public ServerResponse updateUnbindDevice(DeviceDto deviceDto) {

        if (StringUtils.isEmpty(deviceDto.getId())) {
            return ServerResponse.createByErrorMessage("缺少参数");
        }

        DeviceVo deviceVo = deviceDao.findOneDeviceByIdAndPermission(deviceDto);
        if (StringUtils.isEmpty(deviceVo)) {
            return ServerResponse.createByErrorMessage("找不到设备");
        }

        deviceDto.setDeviceNo(deviceVo.getDeviceNo());
        if (StringUtils.isEmpty(deviceVo.getMerchantStoreId()) || "-1".equals(deviceVo.getMerchantStoreId())) {
            return ServerResponse.createByErrorMessage("该设备已解绑，请勿重复操作");
        }

        MerchantStore merchantStore = new MerchantStore();
        merchantStore.setId(deviceVo.getMerchantStoreId());
        merchantStore.setUserId(deviceVo.getUserId());
        MerchantStoreVo merchantStoreVo = merchantStoreService.findMerchantStoreByUserIdByStoreId(merchantStore);
        if (StringUtils.isEmpty(merchantStoreVo)) {
            return ServerResponse.createByErrorMessage("在该用户下找不到设备对应的店铺！");
        }

        DeviceDto deviceDtoUpdate = new DeviceDto();
        deviceDtoUpdate.setId(deviceDto.getId());
        deviceDtoUpdate.setAlias(-1);
        deviceDtoUpdate.setMerchantStoreId(-1);
        deviceDtoUpdate.setDeviceTypeId(-1);
        deviceDtoUpdate.setProductId(-1);
        deviceDtoUpdate.setStatus(DeviceStatusEnum.UNBIND.getCode());
        deviceDtoUpdate.setGoodsId(-1L);
        deviceDtoUpdate.setAgreementVersion(-1);
        deviceDtoUpdate.setRateEach(1);
        deviceDtoUpdate.setFaultCode(-1);
        SystemConfig systemConfig = systemConfigService.findOneSystemConfigById(1);
        if (!StringUtils.isEmpty(systemConfig.getUnbindSum())) {
            String key = String.format(RedisKey.UNBIND_SUM, deviceVo.getId());
            Integer unbindSum = (Integer) redisCacheTemplate.opsForValue().get(key);
            if (unbindSum != null && systemConfig.getUnbindSum() <= unbindSum) {
                return ServerResponse.createByErrorMessage("每天设备解绑次数有限，如需继续解绑请明天再解绑");
            }
        }

//        deviceDtoUpdate.setNcetId(0);
        Integer count = deviceDao.updateDeviceById(deviceDtoUpdate);
        if (count > 0) {
            // 重置备注名称
            DeviceDto remarkNameDeviceDto = new DeviceDto();
            remarkNameDeviceDto.setId(deviceDto.getId());
            remarkNameDeviceDto.setRemarkName(null);
            deviceDao.updateDeviceRemarkNameById(remarkNameDeviceDto);

            // 控制解绑次数
            if (!StringUtils.isEmpty(systemConfig.getUnbindSum())) {
                Calendar calendar = Calendar.getInstance();
                calendar.add(Calendar.DAY_OF_MONTH, 1);//将日加1
                calendar.set(Calendar.HOUR_OF_DAY, 0);//控制时
                calendar.set(Calendar.MINUTE, 0);//控制分
                calendar.set(Calendar.SECOND, 0);//控制秒
                calendar.set(Calendar.MILLISECOND, 0);//毫秒
                Calendar currentDate = Calendar.getInstance();
                //通过以上操作就得到了一个currentDate明天的0时0分0秒的Calendar对象，然后相减即可得到到明天0时0点0分0秒的时间差
                Integer seconds = (int) ((calendar.getTime().getTime() - currentDate.getTime().getTime()) / 1000);
                String key = String.format(RedisKey.UNBIND_SUM, deviceVo.getId());
                Integer unbindSum = (Integer) redisCacheTemplate.opsForValue().get(key);
                if (unbindSum == null) {
                    redisCacheTemplate.opsForValue().set(key, 1, seconds, TimeUnit.SECONDS);
                } else {
                    redisCacheTemplate.opsForValue().set(key, unbindSum + 1, seconds, TimeUnit.SECONDS);
                }
            }

            //售货机绑定的商品下架
            if (
                    deviceVo.getDeviceTypeId().equals(DeviceTypeEnum.VENDING_MACHINE.getCode())
                            || deviceVo.getDeviceTypeId().equals(DeviceTypeEnum.SCREEN_VENDING_MACHINE.getCode())
                            || deviceVo.getDeviceTypeId().equals(DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode())
                            || deviceVo.getDeviceTypeId().equals(DeviceTypeEnum.GASHAPON_MACHINE.getCode())
            ) {
                log.info("售货机、扭蛋机绑定的商品下架");
                CommodityStoreUpDownDto commodityStoreUpDownDto = new CommodityStoreUpDownDto();
                commodityStoreUpDownDto.setStatus(CommodityStoreUpDownEnum.OFF_SHELF.getCode());
                commodityStoreUpDownDto.setDeviceId(deviceVo.getId());
                commodityStoreUpDownService.updateOffTheShelvesById(commodityStoreUpDownDto);
                if (!ObjectUtils.isEmpty(deviceVo.getIsVendmach())
                        && deviceVo.getIsVendmach()) {
                    String command = PositiveDataFrameCMD.penetrate(HuiLianDuiBiJiPositiveDataFrameCMD.boundDeviceOrUnBindOrEditDiscountPackage());
                    log.info("安卓设备需要发 信息变动 信号command:" + command);
                    boolean pub = pubService.pub(command, deviceVo.getDeviceNo(), productKey);
                }
            }
            return ServerResponse.createBySuccess();
        } else {
            return ServerResponse.createBySuccess("解绑失败，请联系平台客服处理");
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServerResponse updateBindDeviceByMerchantStoreId(DeviceDto deviceDto, UserInfo userInfo) {

        log.error("绑定设备号：{}", deviceDto.getDeviceNo());

        String error = "error";
        String result = Optional.ofNullable(deviceDto)
                .map(deviceDtoCheck -> deviceDto.getUserId())
                .map(deviceDtoCheck -> deviceDto.getAgencyId())
                .map(deviceDtoCheck -> deviceDto.getDeviceTypeId())
                .map(deviceDtoCheck -> deviceDto.getMerchantStoreId())
                .map(deviceDtoCheck -> deviceDto.getAlias())
                .map(deviceDtoCheck -> deviceDto.getDeviceNo())
                .orElse("error");

        if (error.equals(result) && (!deviceDto.getDeviceTypeId().equals(DeviceTypeEnum.SUPER_MONEY_CHANGER.getCode())
                && !deviceDto.getDeviceTypeId().equals(DeviceTypeEnum.CONVERTIBLE_CURRENCY_MACHINE.getCode())
                && !deviceDto.getDeviceTypeId().equals(DeviceTypeEnum.VENDING_MACHINE.getCode())
                && !deviceDto.getDeviceTypeId().equals(DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode())
                && !deviceDto.getDeviceTypeId().equals(DeviceTypeEnum.BLEND_VENDING_MACHINE.getCode()))
        ) {
            return ServerResponse.createByErrorMessage("缺少参数");
        }


        DeviceVo isBindingDeviceVo = deviceDao.findOneDeviceByDeviceNo(deviceDto.getDeviceNo());
        if (StringUtils.isEmpty(isBindingDeviceVo) || StringUtils.isEmpty(isBindingDeviceVo.getAgencyId())) {
            return ServerResponse.createByErrorMessage("无效二维码！");
        }

//        DeviceItem deviceItemCondition = new DeviceItem();
//        deviceItemCondition.setDeviceId(isBindingDeviceVo.getId());
//        final List<DeviceItem> deviceItemList = deviceItemService.findAllByDeviceId(deviceItemCondition);
//        isBindingDeviceVo.setDeviceItemList(deviceItemList);

        if (!StringUtils.isEmpty(isBindingDeviceVo.getMerchantStoreId()) && !"-1".equals(String.valueOf(isBindingDeviceVo.getMerchantStoreId()))) {

            // 检查是否已绑定在当前运营下
            Integer[] merchantStoreId = merchantStoreService.findAllMerchantStoreIdByUserId(userInfo);
            for (int i = 0; i < merchantStoreId.length; i++) {
                if (isBindingDeviceVo.getMerchantStoreId().equals(merchantStoreId[i])) {
                    return ServerResponse.createByErrorMessage("设备已绑定，请勿重复操作");
                }
            }

            // 检查是否已绑定在其他运营下
            log.info("deviceDto.getMerchantStoreId():" + deviceDto.getMerchantStoreId());
            log.info("isBindingDeviceVo.getMerchantStoreId():" + isBindingDeviceVo.getMerchantStoreId());
            if (!isBindingDeviceVo.getMerchantStoreId().equals(deviceDto.getMerchantStoreId())) {
                return ServerResponse.createByErrorMessage("已绑定在其他运营商名下");
            }
        }


        DeviceDto deviceDtoCondition = new DeviceDto();
        deviceDtoCondition.setMerchantStoreId(deviceDto.getMerchantStoreId());
        List<Device> deviceList = deviceDao.findAllDeviceByCondition(deviceDtoCondition);
        for (int i = 0; i < deviceList.size(); i++) {
            Device device = deviceList.get(i);
            if (!StringUtils.isEmpty(device.getAlias()) && device.getAlias().equals(deviceDto.getAlias())) {
                return ServerResponse.createByErrorMessage(String.format("编号%s已被使用啦！", deviceDto.getAlias()));
            }
        }

        DeviceDto newDeviceDto = new DeviceDto();
        newDeviceDto.setId(isBindingDeviceVo.getId());
        newDeviceDto.setAlias(deviceDto.getAlias());
        newDeviceDto.setDeviceTypeId(deviceDto.getDeviceTypeId());
        newDeviceDto.setRemarkName(deviceDto.getRemarkName());
        newDeviceDto.setChargingPileRateId(deviceDto.getChargingPileRateId());
        newDeviceDto.setRateEach(deviceDto.getRateEach());
        newDeviceDto.setMerchantStoreId(deviceDto.getMerchantStoreId());
        newDeviceDto.setStatus(DeviceStatusEnum.ON_LINE.getCode());
        newDeviceDto.setGameTime(deviceDto.getGameTime());

        int count = deviceDao.updateDeviceById(newDeviceDto);
        if (count == 0) {
            return ServerResponse.createByErrorMessage("绑定失败，请重新绑定！");
        }

        //售货机
        if (DeviceTypeEnum.VENDING_MACHINE.getCode().compareTo(newDeviceDto.getDeviceTypeId()) == 0 ||
                DeviceTypeEnum.SCREEN_VENDING_MACHINE.getCode().compareTo(newDeviceDto.getDeviceTypeId()) == 0 ||
                DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode().compareTo(newDeviceDto.getDeviceTypeId()) == 0 ||
                DeviceTypeEnum.BLEND_VENDING_MACHINE.getCode().compareTo(newDeviceDto.getDeviceTypeId()) == 0) {
            DeviceDto deviceCondition = new DeviceDto();
            deviceCondition.setDeviceNo(isBindingDeviceVo.getDeviceNo());
            deviceCondition.setDeviceTypeId(newDeviceDto.getDeviceTypeId());
            deviceCondition.setIsBluetooth(true);
            DeviceVo deviceVo = deviceDao.findOneDeviceByDeviceNoJoinProduct(deviceCondition);
            if (ObjectUtils.isEmpty(deviceVo)) {
                throw new RuntimeException("请检查设备供电、串口连接是否正常");
            }
            boolean enabled = false;
            if (!StringUtils.isEmpty(deviceVo.getIsBluetooth()) && deviceVo.getIsBluetooth() && DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode().compareTo(newDeviceDto.getDeviceTypeId()) == 0) {
                Product product = new Product();
                product.setLoginId(30028);//涛说蓝牙版是固定30028登陆标识的 写死就行了
                Product oneProductByCondition = productService.findOneProductByCondition(product);
                if (StringUtils.isEmpty(oneProductByCondition)) {
                    log.info("查询30028登录标识的产品不存在");
                } else {
                    //蓝牙默认货道使能打开状态
                    enabled = true;
                    deviceVo.setCapacity(oneProductByCondition.getCapacity());
                    deviceVo.setHierarchyTotal(oneProductByCondition.getHierarchyTotal());
                    deviceVo.setFreightLaneTotal(oneProductByCondition.getFreightLaneTotal());
                }
            }
            log.info("售货机findOneDeviceByDeviceNoJoinProduct方法查询到的信息{}", deviceVo);
            DeviceDto dd = new DeviceDto();
            dd.setProductDisplayType(DeviceProductDisplayTypeEnum.FREIGHT_LANE_SORT.getCode());
            dd.setId(deviceVo.getId());
            deviceDao.updateCustomerBuySet(dd);

            DisplayRackDto displayRackDto = new DisplayRackDto();
            displayRackDto.setDeviceId(deviceVo.getId());
            if (!StringUtils.isEmpty(deviceDto.getRemarkName())) {
                displayRackDto.setName(deviceDto.getRemarkName());
            } else {
                displayRackDto.setName(deviceVo.getDeviceNo() + "_售货机");
            }
            if (RoleEnum.SUB_ACCOUNT.getRoleId().equals(userInfo.getRoleId())) {
                displayRackDto.setUserId(userInfo.getParentId());
            } else {
                displayRackDto.setUserId(userInfo.getId());
            }

            DisplayRack displayRack = displayRackService.findDisplayByDeviceId(deviceVo.getId());
            log.info("售货机findDisplayByDeviceId方法查询到的信息{}", displayRack);
            if (StringUtils.isEmpty(displayRack)) {
                log.info("售货机:{}未查询到已有货道,进入生成货道", deviceVo.getDeviceNo());
                displayRackDto.setMerchantStoreId(deviceVo.getMerchantStoreId());
                displayRackDto.setType(DisplayRackEnum.EQUIPMENT_DISPLAY_RACK.getCode());
                displayRackDto.setIsDelete(false);
                displayRackService.insert(displayRackDto);
                if (ObjectUtils.isEmpty(deviceVo.getHierarchyTotal()) || deviceVo.getHierarchyTotal() < 1) {
                    deviceVo.setHierarchyTotal(1);
                }
                if (ObjectUtils.isEmpty(deviceVo.getFreightLaneTotal()) || deviceVo.getFreightLaneTotal() < 1) {
                    deviceVo.setFreightLaneTotal(1);
                }
                for (int i = 1; i < deviceVo.getHierarchyTotal() + 1; i++) {
                    for (int j = 1; j < deviceVo.getFreightLaneTotal() + 1; j++) {
                        DisplayRackItem displayRackItem = new DisplayRackItem();
                        displayRackItem.setDisplayRackId(displayRackDto.getId());
                        displayRackItem.setHierarchy(i);
                        displayRackItem.setFreightLane(j);
                        displayRackItem.setAlias("" + i + (j < 10 ? "0" + j : j));
                        displayRackItem.setCapacity(deviceVo.getCapacity());
                        displayRackItem.setStock(0);
                        displayRackItem.setWarnStock(0);
                        displayRackItem.setExistStock(0);
                        displayRackItem.setReserveStock(0);
                        displayRackItem.setEnabled(enabled);
                        displayRackItem.setEnableWarnStock(false);
                        displayRackItem.setEnableWarnPeriodReminder(false);
                        displayRackItem.setVersion(0);
                        log.info("插入货道{}", displayRackItem);
                        if (DeviceTypeEnum.BLEND_VENDING_MACHINE.getCode().compareTo(newDeviceDto.getDeviceTypeId()) == 0) {
                            if (i <= deviceVo.getSpringMachineHierarchyTotal()) {
                                displayRackItem.setDeviceTypeId(DeviceTypeEnum.VENDING_MACHINE.getCode());
                            } else {
                                displayRackItem.setDeviceTypeId(DeviceTypeEnum.OPEN_DOOR_VENDING_MACHINE.getCode());
                            }
                        } else if (DeviceTypeEnum.SCREEN_VENDING_MACHINE.getCode().compareTo(newDeviceDto.getDeviceTypeId()) == 0) {
                            displayRackItem.setDeviceTypeId(DeviceTypeEnum.VENDING_MACHINE.getCode());
                        } else {
                            displayRackItem.setDeviceTypeId(newDeviceDto.getDeviceTypeId());
                        }
                        displayRackItemService.insert(displayRackItem);
                    }
                }
            } else {
                log.info("售货机:{}查询到已有货道,把已有货道信息刷新", deviceVo.getDeviceNo());
                //1.把以前绑定的货道commodityId,stock,status 清空
                displayRackItemService.updateRestoreByDisplayRackId(displayRack.getId());
                log.info("updateRestoreByDisplayRackId修改displayRack.getId:{}", displayRack.getId());
                //2.覆盖原货道所属的userId merchantStoreId
                DisplayRack updateDisplayRack = new DisplayRack();
                updateDisplayRack.setId(displayRack.getId());
                updateDisplayRack.setMerchantStoreId(deviceVo.getMerchantStoreId());
                if (RoleEnum.SUB_ACCOUNT.getRoleId().equals(userInfo.getRoleId())) {
                    updateDisplayRack.setUserId(userInfo.getParentId());
                } else {
                    updateDisplayRack.setUserId(userInfo.getId());
                }
                displayRackService.updateById(updateDisplayRack);
                log.info("updateById修改对象{}", updateDisplayRack);
            }
        }

        redisCacheTemplate.delete(String.format(RedisKey.DEBUG_CONSUME_SUM, deviceDto.getDeviceNo()));

        return ServerResponse.createBySuccess(deviceDto);
    }


}
